/*
 * Created on 2004-10-27
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package com.koron.ui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

/**
 * 这是一个JAVA的布局类.
 * 该类把一个容器分成x行,y列,间距为xgap,ygap,每行(列)均可以设定宽(高),即可为绝对表示(数值)也可以为相对(百分比)
 * 然后使用merge和splite方法在原有的格上合并或拆分成新单元格. 然后按从左到右,从上到下的顺序排序,每个组件加入都可以放进相对应的格内.
 * 每格的组件填充方式有:扩展填充,最佳尺寸两种方式
 */
public class MutableGridLayout implements LayoutManager
{
	public static final int EXPAND = 1;

	public static final int PREFERRED = 2;

	public static final int LEFT = 1;

	public static final int CENTER = 2;

	public static final int RIGHT = 3;

	public static final int TOP = 1;

	public static final int MIDDLE = 2;

	public static final int BOTTOM = 3;

	int cols, rows, colGap, rowGap; // 行数,列数,以及间隔

	int col, row, colWeight, rowWeight;// 从哪格占到哪格,共有几个组件

	double[] gridWidth, gridHeight;// 每格的宽,高,如果大于1则是绝对宽度,如果小于一则是相对宽度

	MutableGridLayout[] box;

	private int fill = 1, align = 1, valign = 1;// 填充模式

	boolean isBlank = false;// 是否用作分隔用,缺省为否

	int[] xValue, yValue;// 临时生成每格的起始位置

	int[] tmpWidth, tmpHeight;// 临时存储每格的宽高

	int[] tmpW, tmpH;// 监时存储每行的最小宽度和每列的最小高度

	private Dimension minSize; // 最小宽度,高度

	private Dimension perferredSize;// 最佳宽度,高度

	/**
	 * 创建一个LAYOUT,有x列,y行,列间距为xGap,行间距为yGap
	 * 
	 * @param cols
	 *            列数
	 * @param rows
	 *            行数
	 * @param xGap
	 *            列间距
	 * @param yGap
	 *            行间距
	 */
	public MutableGridLayout(int cols, int rows, int xGap, int yGap)
	{
		this.cols = cols;
		this.rows = rows;
		this.colGap = xGap;
		this.rowGap = yGap;
		gridWidth = new double[cols];
		gridHeight = new double[rows];
		for (int i = 0; i < gridWidth.length; i++)
		{
			gridWidth[i] = 1. / cols;
		}
		for (int i = 0; i < gridHeight.length; i++)
		{
			gridHeight[i] = 1. / rows;
		}
		col = 0;
		row = 0;
		colWeight = 1;
		rowWeight = 1;
		int size = rows * cols;
		box = new MutableGridLayout[size];
		for (int i = 0; i < cols; i++)
		{
			for (int j = 0; j < rows; j++)
			{
				box[j * cols + i] = new MutableGridLayout(i, j, 1, 1, 1, 1,
						xGap, yGap);
			}
		}
	}

	/**
	 * 创建一个LAYOUT,有x列,y行,列间距为xGap,行间距为yGap
	 * 
	 * @param cols
	 *            列数
	 * @param rows
	 *            行数
	 * @param xGap
	 *            列间距
	 * @param yGap
	 *            行间距
	 * @param width
	 *            每列的宽度
	 * @param height
	 *            每行的高度
	 */
	public MutableGridLayout(int cols, int rows, int xGap, int yGap,
			double[] width, double[] height)
	{
		this.cols = cols;
		this.rows = rows;
		this.colGap = xGap;
		this.rowGap = yGap;
		gridWidth = width;
		gridHeight = height;
		col = 0;
		row = 0;
		colWeight = 1;
		rowWeight = 1;
		int size = cols * rows;
		box = new MutableGridLayout[size];
		for (int i = 0; i < cols; i++)
		{
			for (int j = 0; j < rows; j++)
			{
				box[i + j * cols] = new MutableGridLayout(i, j, 1, 1, 1, 1,
						xGap, yGap);
			}
		}
	}

	/**
	 * 
	 * @param xPos
	 *            父级的X轴
	 * @param yPos
	 *            父级的Y轴
	 * @param xWidth
	 *            父级的宽度
	 * @param yHeight
	 *            父级的高度
	 * @param cols
	 *            分成X格
	 * @param rows
	 *            分成Y格
	 * @param xGap
	 *            X的间格
	 * @param yGap
	 *            Y的间格
	 */
	public MutableGridLayout(int xPos, int yPos, int xWidth, int yHeight,
			int cols, int rows, int xGap, int yGap)
	{
		this.col = xPos;
		this.row = yPos;
		this.colWeight = xWidth;
		this.rowWeight = yHeight;
		this.cols = cols;
		this.rows = rows;
		this.colGap = xGap;
		this.rowGap = yGap;
		gridWidth = new double[cols];
		gridHeight = new double[rows];
		for (int i = 0; i < gridWidth.length; i++)
		{
			gridWidth[i] = 1. / cols;
		}
		for (int i = 0; i < gridHeight.length; i++)
		{
			gridHeight[i] = 1. / rows;
		}
		int size = cols * rows;
		if (size != 1)
		{
			box = new MutableGridLayout[size];
			for (int i = 0; i < cols; i++)
			{
				for (int j = 0; j < rows; j++)
				{
					box[i + j * cols] = new MutableGridLayout(i, j, 1, 1, 1, 1,
							xGap, yGap);
				}
			}
		}
	}

	/**
	 * 合并单元格
	 * 
	 * @param startX
	 *            起始X位置
	 * @param startY
	 *            起始Y位置
	 * @param endX
	 *            结束X位置
	 * @param endY
	 *            结束Y位置
	 */
	public void merge(int startX, int startY, int endX, int endY)
	{
		int size = box.length;
		for (int i = 0; i < box.length; i++)
		{
			if (!(box[i].col < startX
					|| box[i].col + box[i].colWeight - 1 > endX
					|| box[i].row < startY || box[i].row + box[i].rowWeight - 1 > endY))
			{
				box[i] = null;
				size--;
			}
		}
		MutableGridLayout[] tmpBox = box;
		box = new MutableGridLayout[size + 1];
		int tmpPos = 0;
		boolean hadAdd = false;
		for (int i = 0; i < tmpBox.length; i++)
		{
			if (tmpBox[i] != null)
			{
				box[tmpPos] = tmpBox[i];
				tmpPos++;
			} else
			{
				if (!hadAdd)
				{
					box[tmpPos] = new MutableGridLayout(startX, startY, endX
							- startX + 1, endY - startY + 1, 1, 1, colGap,
							rowGap);
					tmpPos++;
					hadAdd = true;
				}
			}
			// if(tmpBox[i]!=null)
			// {
			// if(hadAdd)
			// {
			// box[tmpPos] =tmpBox[i];
			// tmpPos ++;
			// }
			// else
			// {
			// if(tmpBox[i].row>startY || (tmpBox[i].row==startY &&
			// tmpBox[i].col>startX))
			// {
			// box[tmpPos++] = new
			// MutableGridLayout(startX,startY,endX-startX+1,endY-startY+1,1,1,colGap,rowGap);
			// hadAdd=true;
			// }
			// box[tmpPos] =tmpBox[i];
			// tmpPos ++;
			// }
			// }
		}
	}

	/**
	 * 拆分当前格,间格采用当前格的间格
	 * 
	 * @param x
	 *            行数
	 * @param y
	 *            列数
	 */
	public void split(int x, int y)
	{
		split(x, y, colGap, rowGap);
	}

	/**
	 * 拆分当前格
	 * 
	 * @param x
	 *            行数
	 * @param y
	 *            列数
	 * @param xGap
	 *            间隔
	 * @param yGap
	 *            间隔
	 */
	public void split(int x, int y, int xGap, int yGap)
	{
		this.cols = x;
		this.rows = y;
		gridWidth = new double[x];
		gridHeight = new double[y];
		for (int i = 0; i < gridWidth.length; i++)
		{
			gridWidth[i] = 1. / x;
		}
		for (int i = 0; i < gridHeight.length; i++)
		{
			gridHeight[i] = 1. / y;
		}
		this.colGap = xGap;
		this.rowGap = yGap;
		box = new MutableGridLayout[x * y];
		for (int i = 0; i < x; i++)
		{
			for (int j = 0; j < y; j++)
			{
				box[i + j * x] = new MutableGridLayout(i, j, 1, 1, 1, 1, xGap,
						yGap);
			}
		}
	}

	/**
	 * 获取x,y这格的Box
	 * 
	 * @param x
	 *            x轴位置
	 * @param y
	 *            y轴位置
	 * @return 格子
	 */
	public MutableGridLayout getBox(int col, int row)
	{
		for (int i = 0; i < box.length; i++)
		{
			if (box[i].col <= col && box[i].col + box[i].colWeight > col
					&& box[i].row <= row && box[i].row + box[i].rowWeight > row)
				return box[i];
		}
		throw new IndexOutOfBoundsException();
	}

	/**
	 * 返回该格有几个组件
	 * 
	 * @return 组件个数
	 */
	public int getSize()
	{
		int size = 0;
		if (isBlank())
			return 0;
		if (box == null)
			return 1;
		for (int i = 0; i < box.length; i++)
		{
			size += box[i].getSize();
		}
		return size;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String,
	 *      java.awt.Component)
	 */
	public void addLayoutComponent(String name, Component comp)
	{
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
	 */
	public void layoutContainer(Container parent)
	{
		synchronized (parent.getTreeLock())
		{
			Insets insets = parent.getInsets();
			int width = parent.getWidth() - insets.left - insets.right;
			int height = parent.getHeight() - insets.top - insets.bottom;
			initSize(0, parent.getComponents(), true);
			initBox(insets.left, insets.top, width, height, true);
			setCompoment(0, parent.getComponents());

		}
	}

	/**
	 * 初始有组件格子的最小尺寸以及最佳尺寸,以及每行的宽,列的高,使用递推的方法.未完成
	 * 
	 * @param startValue
	 *            开始的组件位置
	 * @param components
	 *            组件
	 * @return 下一个排的组件
	 */
	public int initSize(int startValue, Component[] components,
			boolean outerBorder)
	{
		for (int i = 0; i < box.length; i++)
		{
			if (box[i].box == null && !box[i].isBlank())// 如果有组件
			{
				if (startValue < components.length)
				{
					box[i].minSize = components[startValue].getMinimumSize();
					box[i].perferredSize = components[startValue]
							.getPreferredSize();
				} else
				{
					box[i].minSize = new Dimension(0, 0);
					box[i].perferredSize = new Dimension(0, 0);
				}
				startValue++;
			} else if (!box[i].isBlank())// 如果包含子格
			{
				startValue = box[i].initSize(startValue, components, false);
			} else
			// 如果是分隔符
			{
				box[i].minSize = new Dimension(0, 0);
				box[i].perferredSize = new Dimension(0, 0);
			}
		}
		// 计算当前格的最小尺寸和最佳尺寸
		int minWidth = 0, minHeight = 0, perferredWidth = 0, perferredHeight = 0;
		if (outerBorder)
		{
			perferredWidth = minWidth = cols * colGap + colGap;
			perferredHeight = minHeight = rows * rowGap + rowGap;
		} else
		{
			perferredWidth = minWidth = cols * colGap - colGap;
			perferredHeight = minHeight = rows * rowGap - rowGap;
		}
//		int tmpMin, tmpPerferred;

		tmpW = new int[cols];
		tmpH = new int[rows];
		for (int i = 0; i < cols; i++)
		{
			for (int j = 0; j < rows; j++)
			{
				MutableGridLayout tmpBox = getBox(i, j);
				if (tmpBox.colWeight == 1)
				{
					tmpW[i] = Math.max(tmpW[i], (int) tmpBox.getPerferredSize()
							.getWidth());
				}
			}
		}

		for (int i = 0; i < rows; i++)
		{
			for (int j = 0; j < cols; j++)
			{
				MutableGridLayout tmpBox = getBox(j, i);
				if (tmpBox.rowWeight == 1)
				{
					tmpH[i] = Math.max(tmpH[i], (int) tmpBox.getPerferredSize()
							.getHeight());
				}
			}
		}
		for (int i = 0; i < cols; i++)
		{
			minWidth += tmpW[i];
		}
		for (int i = 0; i < rows; i++)
		{
			minHeight += tmpH[i];
		}
		minSize = new Dimension(minWidth, minHeight);

		// 计算列宽
		double maxRate = 0;
		// double tmpRate = 0;
		// double[] rate = new double[cols];
		for (int i = 0; i < cols; i++)
		{
			if (gridWidth[i] > 1)
			{
				tmpW[i] = Math.max(tmpW[i], (int) gridWidth[i]);
			}
		}
		for (int i = 0; i < cols; i++)
		{
			if (gridWidth[i] <= 1)
			{
				// rate[i] = tmpW[i]/gridWidth[i];
				maxRate = Math.max(maxRate, tmpW[i] / gridWidth[i]);
			}
		}
		for (int i = 0; i < cols; i++)
		{
			if (gridWidth[i] > 1)
			{
				perferredWidth += tmpW[i];

			} else
			{
				perferredWidth += gridWidth[i] * maxRate;
			}
		}
		// //由gridWidth(用户设置的宽),tmpW(算出来的宽),rate(比例)
		// double[] tmpGridWidth = new double[gridWidth.length];
		// for (int i = 0; i < tmpGridWidth.length; i++)
		// {
		// tmpGridWidth[i] = gridWidth[i];
		// }
		// // setSize(tmpGridWidth,tmpWidth,tmpW);
		//		
		// 计算行高
		maxRate = 0;
		for (int i = 0; i < rows; i++)
		{
			if (gridHeight[i] > 1)
			{
				tmpH[i] = Math.max(tmpH[i], (int) gridHeight[i]);
			}
		}
		for (int i = 0; i < rows; i++)
		{
			if (gridHeight[i] <= 1)
			{
				maxRate = Math.max(maxRate, tmpH[i] / gridHeight[i]);
			}
		}
		for (int i = 0; i < rows; i++)
		{
			if (gridHeight[i] > 1)
			{
				perferredHeight += tmpH[i];
			} else
			{
				perferredHeight += gridHeight[i] * maxRate;
			}
		}
		//		
		perferredSize = new Dimension(perferredWidth, perferredHeight);
		return startValue;
	}

	/**
	 * 设置组件
	 * 
	 * @param startValue
	 *            开始值
	 * @param components
	 *            组件
	 * @return 下个需排序的组件位置
	 */
	private int setCompoment(int startValue, Component[] components)
	{
		for (int i = 0; i < box.length; i++)
		{
			if (box[i].box == null && !box[i].isBlank())
			{
				if (startValue < components.length)
				{
					int left = xValue[box[i].col];
					int top = yValue[box[i].row];
					Dimension d1 = getBoxDimension(i);
					Dimension d2 = components[startValue].getPreferredSize();
					if (box[i].fill == MutableGridLayout.PREFERRED)
					{
						// 计算宽和高
						d1.width = Math.min(d1.width, d2.width);
						d1.height = Math.min(d1.height, d2.height);
						components[startValue].setSize(components[startValue]
								.getPreferredSize());
						// 设置位置
						d2 = getBoxDimension(i);
						if (box[i].align == CENTER)
							left += (d2.width - d1.width) / 2;
						else if (box[i].align == RIGHT)
							left += (d2.width - d1.width);
						if (box[i].valign == MIDDLE)
							top += (d2.height - d1.height) / 2;
						else if (box[i].valign == BOTTOM)
							top += (d2.height - d1.height);
					}
					components[startValue].setSize(d1);
					components[startValue].setLocation(left, top);
				}
				startValue++;
			} else if (!box[i].isBlank())
			{
				startValue = box[i].setCompoment(startValue, components);
			}
		}
		return startValue;
	}

	/**
	 * 初始化每格的位置,并初始化其下所有格的位置
	 * 
	 * @param xPos
	 *            开始位置的x轴座标
	 * @param yPos
	 *            开始位置的y轴座标
	 * @param width
	 *            宽度
	 * @param height
	 *            高度
	 * @param outerBorder
	 *            最外边是否有边缘
	 */
	private void initBox(int xPos, int yPos, int width, int height,
			boolean outerBorder)
	{

		xValue = new int[cols];// x轴的座标
		yValue = new int[rows];// y轴的座标
		tmpWidth = new int[cols];// 每列的宽度
		tmpHeight = new int[rows];// 每行的宽度

		int tmpValue = width - (outerBorder ? (cols + 1) : (cols - 1)) * colGap;
//		double tmpPercent = 0;
		int tmp = xPos;
		tmp += outerBorder ? colGap : 0;
		// 计算每列的开始位置,以及列宽
		double[] tmpGridWidth = new double[gridWidth.length];
		for (int i = 0; i < tmpGridWidth.length; i++)
		{
			tmpGridWidth[i] = gridWidth[i];
		}

		setSize(tmpGridWidth, tmpWidth, tmpW, tmpValue);
		int totalWidth = 0;
		for (int i = 0; i < cols; i++)
		{
			totalWidth += tmpWidth[i];
		}
		if (totalWidth > width)
		{
			for (int i = 0; i < cols; i++)
			{
				tmpWidth[i] = tmpWidth[i] * width / totalWidth;
			}
		}

		for (int i = 0; i < cols; i++)
		{
			xValue[i] = tmp;
			tmp += tmpWidth[i] + colGap;
		}

		// for (int i = 0; i < cols; i++)
		// {
		// if(gridWidth[i] >1)tmpValue -= gridWidth[i];
		// else tmpPercent += gridWidth[i];
		// }
		//		
		// for (int i = 0; i < cols; i++)
		// {
		// xValue[i] = tmp;
		// if(gridWidth[i]>1)
		// {
		// tmp += gridWidth[i]+colGap;
		// tmpWidth[i] = (int)gridWidth[i];
		// }
		// else
		// {
		// tmp += tmpValue*gridWidth[i]/tmpPercent+colGap;
		// tmpWidth[i] = (int)(tmpValue*gridWidth[i]/tmpPercent);
		// }
		// }

		// 计算每行的开始位置以及行高
		tmpValue = height - (outerBorder ? (rows + 1) : (rows - 1)) * rowGap;
//		tmpPercent = 0;
		tmp = yPos;
		tmp += outerBorder ? rowGap : 0;

		tmpGridWidth = new double[rows];
		for (int i = 0; i < rows; i++)
		{
			tmpGridWidth[i] = gridHeight[i];
		}
		setSize(tmpGridWidth, tmpHeight, tmpH, tmpValue);

		int totalHeight = 0;
		for (int i = 0; i < rows; i++)
		{
			totalHeight += tmpHeight[i];
		}
		if (totalHeight > height)
		{
			for (int i = 0; i < rows; i++)
			{
				tmpHeight[i] = tmpHeight[i] * height / totalHeight;
			}
		}

		for (int i = 0; i < rows; i++)
		{
			yValue[i] = tmp;
			tmp += tmpHeight[i] + rowGap;
		}

		// for (int i = 0; i < rows; i++)
		// {
		// if(gridHeight[i] >1)tmpValue -= gridHeight[i];
		// else tmpPercent += gridHeight[i];
		// }
		// for (int i = 0; i < rows; i++)
		// {
		// yValue[i] = tmp;
		// if(gridHeight[i]>1)
		// {
		// tmp += gridHeight[i]+rowGap;
		// tmpHeight[i] = (int)gridHeight[i];
		// }
		// else
		// {
		// tmp += tmpValue*gridHeight[i]/tmpPercent+rowGap;
		// tmpHeight[i] = (int)(tmpValue*gridHeight[i]/tmpPercent);
		// }
		// }

		if (box != null)
		{
			for (int i = 0; i < box.length; i++)
			{
				if (box[i].box == null)
					continue;
				int tmpBoxWidth = -colGap;
				int tmpBoxHeight = -rowGap;
				for (int j = 0; j < box[i].colWeight; j++)
				{
					tmpBoxWidth += colGap + tmpWidth[box[i].col + j];
				}
				for (int j = 0; j < box[i].rowWeight; j++)
				{
					tmpBoxHeight += rowGap + tmpHeight[box[i].row + j];
				}
				box[i].initBox(xValue[box[i].col], yValue[box[i].row],
						tmpBoxWidth, tmpBoxHeight, false);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
	 */
	public Dimension minimumLayoutSize(Container parent)
	{
		initSize(0, parent.getComponents(), true);
		return minSize;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
	 */
	public Dimension preferredLayoutSize(Container parent)
	{
		initSize(0, parent.getComponents(), true);
		return perferredSize;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
	 */
	public void removeLayoutComponent(Component parent)
	{
	}

	/**
	 * 当前格是否空
	 * 
	 * @return 是否空
	 */
	public boolean isBlank()
	{
		return isBlank;
	}

	/**
	 * 设置当前格为空
	 * 
	 * @param b
	 *            是否为空
	 */
	public void setBlank(boolean b)
	{
		isBlank = b;
	}

	/**
	 * 获取第num格的范围大小
	 * 
	 * @param num
	 *            第num格
	 * @return 格的范围
	 */
	private Dimension getBoxDimension(int num)
	{
		int tmpWidth = -colGap, tmpHeight = -rowGap;
		for (int i = 0; i < box[num].colWeight; i++)
		{
			tmpWidth += this.tmpWidth[box[num].col + i] + colGap;
		}
		for (int i = 0; i < box[num].rowWeight; i++)
		{
			tmpHeight += this.tmpHeight[box[num].row + i] + rowGap;
		}
		return new Dimension(tmpWidth, tmpHeight);
	}

	/**
	 * 设置第num列的宽度为width
	 * 
	 * @param num
	 *            列数
	 * @param width
	 *            宽度
	 */
	public void setWidth(int num, double width)
	{
		if (num < gridWidth.length)
			gridWidth[num] = width;
		else
			throw new IndexOutOfBoundsException();
	}

	/**
	 * 设置第num行的宽度为height
	 * 
	 * @param num
	 *            行数
	 * @param height
	 *            高度
	 */
	public void setHeight(int num, double height)
	{
		if (num < gridHeight.length)
			gridHeight[num] = height;
		else
			throw new IndexOutOfBoundsException();
	}

	/**
	 * 获取最小大小
	 * 
	 * @return 最小大小
	 */
	public Dimension getMininumSize()
	{
		return minSize;
	}

	/**
	 * 获取最佳尺寸
	 * 
	 * @return 最佳尺寸
	 */
	public Dimension getPerferredSize()
	{
		return perferredSize;
	}

	/**
	 * 获取填充方式
	 * 
	 * @return 填充方式
	 */
	public int getFill()
	{
		return fill;
	}

	/**
	 * 设置填充方式
	 * 
	 * @param i
	 *            填充方式
	 */
	public void setFill(int fill)
	{
		this.fill = fill;
	}

	/**
	 * 获取填充时水平对齐方式
	 * 
	 * @return 填充时水平对齐方式
	 */
	public int getAlign()
	{
		return align;
	}

	/**
	 * 获取填充时垂直对齐方式
	 * 
	 * @return 填充时垂直对齐方式
	 */
	public int getValign()
	{
		return valign;
	}

	/**
	 * 设置填充时水平对齐方式
	 * 
	 * @param i
	 *            填充时水平对齐方式
	 */
	public void setAlign(int align)
	{
		this.align = align;
	}

	/**
	 * 设置填充时垂直对齐方式
	 * 
	 * @param i
	 *            填充时垂直对齐方式
	 */
	public void setValign(int valign)
	{
		this.valign = valign;
	}

	public static void main(String[] args)
	{
		MutableGridLayout ml = new MutableGridLayout(8, 8, 5, 5);
		ml.merge(2, 0, 3, 0);
		ml.getBox(2, 0).split(2, 1);
		ml.merge(1, 1, 3, 1);
		ml.merge(5, 1, 7, 1);
		ml.merge(5, 2, 7, 2);
		ml.merge(5, 3, 7, 3);
		ml.merge(5, 4, 7, 4);
		ml.getBox(6, 5).setBlank(true);
		ml.getBox(7, 5).setBlank(true);
		ml.getBox(4, 7).setBlank(true);
		ml.getBox(5, 7).setBlank(true);
		ml.getBox(6, 7).setBlank(true);
		ml.getBox(7, 7).setBlank(true);
		ml.merge(0, 7, 1, 7);
		ml.setWidth(0, 0.1);
		ml.setWidth(1, 0.15);
		ml.setWidth(2, 0.10);
		ml.setWidth(3, 0.15);
		ml.setWidth(4, 0.1);
		ml.setWidth(5, 0.15);
		ml.setWidth(6, 0.10);
		ml.setWidth(7, 0.15);
		JFrame jf = new JFrame("HR");
		jf.getContentPane().setLayout(ml);

		String[] lbl = new String[]
		{ "姓名", "出生年月", "民族", "身份证号码", "家庭住址", "婚姻状况", "证件号码", "藉贯", "毕业院校",
				"专业", "学历", "到职日期", "离职日期", "状况", "部门", "职位", "分机", "手机",
				"家庭电话", "应急电话", "电子邮件", "密码" };
		JTextField[] jtf = new JTextField[22];
		JRadioButton jb1 = new JRadioButton("男");
		JRadioButton jb2 = new JRadioButton("女");
		ButtonGroup bg = new ButtonGroup();
		bg.add(jb1);
		bg.add(jb2);
		JCheckBox jcb = new JCheckBox("是否系统使用者");

		
		for (int i = 0; i < lbl.length; i++)
		{
			jf.getContentPane().add(new JLabel(lbl[i]+":"));
			jtf[i] = new JTextField();
			jf.getContentPane().add(jtf[i]);
			if (i == 0)
			{
				jf.getContentPane().add(jb1);
				jf.getContentPane().add(jb2);
			} else if (i == 20)
			{
				jf.getContentPane().add(jcb);
			}

		}

		int tmpCount = jf.getContentPane().getComponentCount();
		for (int i = 0; i < tmpCount; i++)
		{
			jf.getContentPane().getComponent(i).setFont(new Font("宋体",Font.PLAIN,14));
		}
		
		jf.setSize(600,250);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setVisible(true);
		
		// int width = 400;
		// double[] gridWidth = new double[4];
		// gridWidth[0] =100;
		// gridWidth[1] =0.2;
		// gridWidth[2] =0.6;
		// gridWidth[3] =0.4;
		// int[] tmpWidth = new int[4];
		// int[] tmpW = new int[4];
		// tmpW[0] = 20;
		// tmpW[1] = 0;
		// tmpW[2] = 10;
		// tmpW[3] = 150;
		// ml.setSize(gridWidth,tmpWidth,tmpW,width);
		// for (int i = 0; i < tmpWidth.length; i++)
		// {
		// System.out.println("width:\t"+tmpWidth[i]);
		// }
		// System.out.println("===========");
		// for (int i = 0; i < tmpWidth.length; i++)
		// {
		// System.out.println("width:\t"+gridWidth[i]);
		// }
	}

	/**
	 * 
	 * @param gridWidth
	 *            格宽
	 * @param tmpWidth
	 *            计算出的宽
	 * @param tmpW
	 *            最小宽度
	 * @param width
	 *            总宽
	 * @return
	 */
	private boolean setSize(double[] gridWidth, int[] tmpWidth, int[] tmpW,
			int width)
	{

//		int[] rate = new int[gridWidth.length];
		double percent = 0;
		int intWidth = width;
		boolean finished = false;
		for (int i = 0; i < gridWidth.length; i++)
		{
			if (gridWidth[i] > 1)
				tmpWidth[i] = (int) Math.max(gridWidth[i], tmpW[i]);
		}
		while (!finished)
		{
			intWidth = width;
			percent = 0;
			finished = true;
			for (int i = 0; i < gridWidth.length; i++)
			{
				if (gridWidth[i] > 1 || gridWidth[i] < 0)
				{
					intWidth -= tmpWidth[i];
				} else
					percent += gridWidth[i];
			}
			for (int i = 0; i < gridWidth.length; i++)
			{
				if (gridWidth[i] <= 1 && gridWidth[i] > 0)// 是百分比
				{
					if (tmpW[i] > intWidth * gridWidth[i] / percent)
					{
						tmpWidth[i] = tmpW[i];
						gridWidth[i] = -1;
						finished = false;
					} else
					{
						tmpWidth[i] = (int) (intWidth * gridWidth[i] / percent);
					}
				}
			}
		}

		return false;
	}

}